/**
 * Copyright (c) Software Institute of PKU
 * All rights reserved. 
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 */
package edu.pku.sei.modeler.model.core;

import org.eclipse.emf.ecore.EClass;
import org.w3c.dom.Element;

import edu.pku.sei.gefcommon.descriptor.annotation.MethodProperty;
import edu.pku.sei.modeler.model.xml.XMLUtility;

/**
 * @author Zhao Yi
 * @author xy
 *
 */
public class MetaStructuralFeature extends MetaTypedElement{
	protected MetaClass containingClass;
	
	protected static final boolean CHANGEABLE_DEFAULT = true;
	protected boolean changeableFlag = CHANGEABLE_DEFAULT;
	
	protected static final boolean DERIVED_DEFAULT = false;
	protected boolean derivedFlag = DERIVED_DEFAULT;
	
	
	@MethodProperty(
			id = "STRUCTURALFEATURE_CONTAININGCLASS",
			catalog = "Model",
			name = CorePackage.STRUCTURALFEATURE_CONTAININGCLASS,
			setter = "setContainingClass"
			)
	public MetaClass getContainingClass(){
		return containingClass;
	}
	
	void setContainingClass(MetaClass newContainingClass) {
		MetaClass oldContainingClass = containingClass;
		containingClass = newContainingClass;
		firePropertyChange(CorePackage.STRUCTURALFEATURE_CONTAININGCLASS, oldContainingClass, newContainingClass);
	}

	@MethodProperty(
			id = "STRUCTURALFEATURE_IS_CHANGEABLE",
			catalog = "Model",
			name = CorePackage.STRUCTURALFEATURE_CHANGEABLEFLAG,
			setter = "setChangeable"
			)
	public boolean isChangeable() {
		return changeableFlag;
	}
	
	public void setChangeable(boolean newChangeable) {
		boolean oldChangeable = changeableFlag;
		changeableFlag = newChangeable;
    	firePropertyChange(CorePackage.STRUCTURALFEATURE_CHANGEABLEFLAG, oldChangeable, newChangeable);
    }
	
	@MethodProperty(
			id = "STRUCTURALFRATURE_IS_DERIVED",
			catalog = "Model",
			name = CorePackage.STRUCTURALFEATURE_DERIVEDFLAG,
			setter = "setDerived"
			)
	public boolean isDerived() {
		return derivedFlag;
	}
	
	public void setDerived(boolean newDerived) {
		boolean oldDerived = derivedFlag;
		derivedFlag = newDerived;
    	firePropertyChange(CorePackage.STRUCTURALFEATURE_DERIVEDFLAG, oldDerived, newDerived);
    }
	
	public void serialize(Element root) {
		super.serialize(root);
		XMLUtility.xmlInstance.serializeNodeNotContain(root, CorePackage.STRUCTURALFEATURE_CONTAININGCLASS, containingClass);
		XMLUtility.xmlInstance.serializeAttribute(root, CorePackage.STRUCTURALFEATURE_CHANGEABLEFLAG, changeableFlag);
		XMLUtility.xmlInstance.serializeAttribute(root, CorePackage.STRUCTURALFEATURE_DERIVEDFLAG, derivedFlag);
	}
	
	public void deSerialize(Element root) {
		super.deSerialize(root);
		containingClass = (MetaClass)XMLUtility.xmlInstance.deSerializeNodeNotContain(root, CorePackage.STRUCTURALFEATURE_CONTAININGCLASS,this);
		changeableFlag = XMLUtility.xmlInstance.deSerializeBoolean(root, CorePackage.STRUCTURALFEATURE_CHANGEABLEFLAG);
		derivedFlag = XMLUtility.xmlInstance.deSerializeBoolean(root, CorePackage.STRUCTURALFEATURE_DERIVEDFLAG);
	}
	
	@Override
	protected EClass eStaticClass() {
		return EMetaModelPackage.Literals.EMETA_STRUCTURAL_FEATURE;
	}
	
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case EMetaModelPackage.EMETA_STRUCTURAL_FEATURE__CONTAINING_CLASS:
				if (resolve) return getContainingClass();
				return getContainingClass();
			case EMetaModelPackage.EMETA_STRUCTURAL_FEATURE__CHANGEABLE_FLAG:
				return isChangeable() ? Boolean.TRUE : Boolean.FALSE;
			case EMetaModelPackage.EMETA_STRUCTURAL_FEATURE__DERIVED_FLAG:
				return isDerived() ? Boolean.TRUE : Boolean.FALSE;
		}
		return super.eGet(featureID, resolve, coreType);
	}
}
